#ifndef _SMP_MENU_H
#define _SMP_MENU_H

#include "sgl_funcs.h"
#include "sgl_window.h"

enum {
	SMP_MENU_CLEARMENUITEMS,
	SMP_MENU_SETMENUITEM,
	SMP_MENU_SETMENUITEM2,
	SMP_MENU_SETSUBMENU,
	SMP_MENU_CHECKMENUITEM,
	SMP_MENU_DISABLEMENUITEM,
	SMP_MENU_POPUP,
	SMP_MENU_POPUP2,
	SMP_MENU_POPUPFLAT
	//,SMP_MENU_WNDPROC
};

#ifndef SDK_NO_PLUGIN
#define SMP_MENU_WNDPROC  MPS_CODE_SMP_MENU_PROC
#else
#define SMP_MENU_WNDPROC  SMP_Menu_WndProc
#endif

#undef MENU_SUPPORT_SUBMENU
#undef MENU_SUPPORT_CHECK

/**
 * \defgroup controls Common Controls
 * @{
 */

/**
  \defgroup smp_menu Simple Menu

  To work with the simple menu:
  - Setup the menu items
  - Call simple menu APIs to show the menu
  - Response the menu notify message

  Below are the different ways to setup menu items and show a popup menu:
  
  Sample Code 1:
  \code
  	SMP_Menu_ClearMenuItems();
  	SMP_Menu_SetMenuItem(0, ..., 1);
  	SMP_Menu_SetMenuItem(1, ..., 2);
  	SMP_Menu_SetMenuItem(2, ..., 3);
  	...

  	SMP_Menu_Popup(...);
  \endcode

  Sample Code 2:
  \code
  	//global menu items information
	static const DWORD miOptions [] =
	{
		STR_CONNECT,
		STR_EXIT,
		STR_REGISTER,
		...
	};

	//your code
  	SMP_Menu_ClearMenuItems();
	SMP_Menu_SetMenuItem2(0, miOptions, sizeof(miOptions)/sizeof(miOptions[0]));
	...
	
  	SMP_Menu_Popup(...);
  \endcode

  Sample code 3:
  \code
  	//when the popup is a simple menu without submenu, there is a wrapper for sample code 2

  	//global menu items information
	static const DWORD miOptions [] =
	{
		STR_CONNECT,
		STR_EXIT,
		STR_REGISTER,
		...
	};

	SMP_Menu_Popup2(..., miOptions, sizeof(miOptions)/sizeof(miOptions[0]));
  \endcode

  Response to the Menu notify message.

  \code
	case WM_COMMAND:
		WID id = LOWORD(wParam);
		WORD code = HIWORD(wParam); // is the menu item id

		if(id == "the menu id")
		{
			DWORD userdata = (DWORD)lParam; //if setted with the menu item
			switch(code)
			{
			case STR_CONNECT:
				//handle the notify event.
				break;
			case STR_EXIT:
				break;
			case STR_REGISTER:
				break;
			...
			}
		}	
  \endcode

  @ingroup controls
  @{
 */

/**
 * \brief Max Menu items in a menu. Reconfigure it as needed.
 */
#define SMP_MENU_MAX_MENUITEM	20

	/**
	* \name Window Styles
	* @{
	*/

/**
 * \brief Indicates the (x, y) position in popup function is the menu (left, button)
 */
#define SMP_MENUS_BOTTOMLEFT			0x0001L	

#if 0 //not implemented yet
/**
 * \brief Indicates the (x, y) position in popup function is the menu (right, button)
 */
#define SMP_MENUS_BOTTOMRIGHT		0x0002L
#endif

/**
 * \brief Indicates the (x, y) position in popup function is the menu (left, top)
 */
#define SMP_MENUS_TOPLEFT				0x0004L

#if 0 //not implemented yet
/**
 * \brief Indicates the (x, y) position in popup function is the menu (right, top)
 */
#define SMP_MENUS_TOPRIGHT			0x0008L
#endif

/**
 * \brief Indicates that is a flat menu with fixed width.
 *
 * This style only used in SMP_Menu_PopupFlat to show a flat style menu.
 * The flat menu just one level, so do not use this style for a normal menu,
 * it is used by combo box and some other controls.
 */
#define SMP_MENUS_FLAT				0x0010L

	/** @} */

/**
 * \brief Seperator menu item id.
 */
#define SMP_MENU_SEPERATOR		0xffff


	/**
	 * \name Window Member Functions
	 * @{
	 */

#if defined(INCLUDE_IN_PLUG_SGL_SRC) || defined(SDK_NO_PLUGIN)
/**
 * \brief Clear the simple menu items.
 */
int32 SMP_Menu_ClearMenuItems(VOID);

/**
 * \brief Set a menu item with a index.
 * 
 * \param index the menu item index
 * \param id the menu item id
 * \param str the string displayed for the menuitem
 * \param data the menuitem data
 * \param next the next menu item, -1 means have no next menuitem
 */
int32 SMP_Menu_SetMenuItem(int index, WID id, PCWSTR str, DWORD data, int next);

/**
 * \brief Setup menuitems with a string resource array.
 *
 * \param start the start index
 * \param items the string resource array
 * \param size the str array size
 */
int32 SMP_Menu_SetMenuItem2(int start, const DWORD* items, int size);

/**
 * \brief Set a sub menu.
 *
 * \param index the menu item index which will has the submenu
 * \param sub the sub menu items
 */
int32 SMP_Menu_SetSubMenu(int index, int sub);

/**
 * \brief Check a menu item.
 * 
 * \param index the menu item index
 * \param check TRUE checked, FALSE unchecked
 */
int32 SMP_Menu_CheckMenuItem(int index, BOOL check);

/**
 * \brief Disable a menu item.
 *
 * \param index the menu item index
 * \param disable TRUE disalbe, FALSE enable
 */
int32 SMP_Menu_DisableMenuItem(int index, BOOL disable); 

/**
 * \brief Popup the global menu with menuitems.
 *
 * \param id the Menu Window ID
 * \param style the Menu style
 * \param hParent the top-level/modal window handle
 * \param x the left position
 * \param y the top position
 * \param listener the window to handle the WM_COMMAND message
 * \return the global menu handle
 */
//HMENU SMP_Menu_Popup(WID id, DWORD style, HWND hParent, int x, int y, HWND listener);
HMENU SMP_Menu_Popup(PWNDATTR attr, int32 x, int32 y);

/**
 * \brief Popup the global menu with menuitems.
 *
 * \param id the Menu Window ID
 * \param style the Menu style
 * \param hParent the top-level/modal window handle
 * \param x the left position
 * \param y the top position
 * \param items the Menu Item string array
 * \param size the menu item string array size
 * \param listener the window to handle the WM_COMMAND message
 * \return the global menu handle
 */
//HMENU SMP_Menu_Popup2(WID id, DWORD style, HWND hParent, int x, int y, const DWORD* items, int size, HWND listener);
HMENU SMP_Menu_Popup2(PWNDATTR attr, int32 x, int32 y, const DWORD* items, int size);

/**
 * \brief Popup the global flat style menu with fixed width.
 *
 * \param id the Menu Window ID
 * \param style the Menu style
 * \param hParent the top-level/modal window handle
 * \param x the left position
 * \param y the top position
 * \param w the menu width
 * \param listener the window to handle the WM_COMMAND message
 * \return the global menu handle
 */
//HMENU SMP_Menu_PopupFlat(WID id, DWORD style, HWND hParent, int x, int y, int w, HWND listener);
HMENU SMP_Menu_PopupFlat(PWNDATTR attr, int32 x, int32 y, int32 w);

	/** @} */

	/**
	 * \name Window Procedure
	 * @{
	 */

/**
 * \brief The simple menu window procedure.
 *
 * \param hMenu the window handle
 * \param Msg the window message
 * \param wParam the first parameter
 * \param lParam the second parameter
 * \return the result of message process 
 */
LRESULT SMP_Menu_WndProc(HMENU hMenu, UINT Msg, WPARAM wParam, LPARAM lParam);
#else
/**
 * \brief Clear the simple menu items.
 */
#define SMP_Menu_ClearMenuItems() \
	mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_CLEARMENUITEMS, (int32)0, (int32)0, (int32)0, (int32)0, (int32)0)

/**
 * \brief Set a menu item with a index.
 * 
 * \param index the menu item index
 * \param id the menu item id
 * \param str the string displayed for the menuitem
 * \param data the menuitem data
 * \param next the next menu item, -1 means have no next menuitem
 */
#define SMP_Menu_SetMenuItem(index, id, str, data, next) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_SETMENUITEM, (int32)index, (int32)id, (int32)str, (int32)data, (int32)next)

/**
 * \brief Setup menuitems with a string resource array.
 *
 * \param start the start index
 * \param items the string resource array
 * \param size the str array size
 */
#define SMP_Menu_SetMenuItem2(start, items, size) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_SETMENUITEM2, (int32)start, (int32)items, (int32)size, (int32)0, (int32)0)

/**
 * \brief Set a sub menu.
 *
 * \param index the menu item index which will has the submenu
 * \param sub the sub menu items
 */
#define SMP_Menu_SetSubMenu(index, sub) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_SETSUBMENU, (int32)index, (int32)sub, (int32)0, (int32)0, (int32)0)

/**
 * \brief Check a menu item.
 * 
 * \param index the menu item index
 * \param check TRUE checked, FALSE unchecked
 */
#define SMP_Menu_CheckMenuItem(index, check) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_CHECKMENUITEM, (int32)index, (int32)check, (int32)0, (int32)0, (int32)0)

/**
 * \brief Disable a menu item.
 *
 * \param index the menu item index
 * \param disable TRUE disalbe, FALSE enable
 */
#define SMP_Menu_DisableMenuItem(index, disable) \
	mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_DISABLEMENUITEM, (int32)index, (int32)disable, (int32)0, (int32)0, (int32)0)

/**
 * \brief Popup the global menu with menuitems.
 *
 * \param id the Menu Window ID
 * \param style the Menu style
 * \param hParent the top-level/modal window handle
 * \param x the left position
 * \param y the top position
 * \param listener the window to handle the WM_COMMAND message
 * \return the global menu handle
 */
//HMENU SMP_Menu_Popup(WID id, DWORD style, HWND hParent, int x, int y, HWND listener);
#define SMP_Menu_Popup(attr, x, y) \
	(HMENU)mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_POPUP, (int32)attr, (int32)x, (int32)y, (int32)0, (int32)0)

/**
 * \brief Popup the global menu with menuitems.
 *
 * \param id the Menu Window ID
 * \param style the Menu style
 * \param hParent the top-level/modal window handle
 * \param x the left position
 * \param y the top position
 * \param items the Menu Item string array
 * \param size the menu item string array size
 * \param listener the window to handle the WM_COMMAND message
 * \return the global menu handle
 */
//HMENU SMP_Menu_Popup2(WID id, DWORD style, HWND hParent, int x, int y, const DWORD* items, int size, HWND listener);
#define SMP_Menu_Popup2(attr, x, yitems, size) \
	(HMENU)mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_POPUP2, (int32)attr, (int32)x, (int32)y, (int32)items, (int32)size)

/**
 * \brief Popup the global flat style menu with fixed width.
 *
 * \param id the Menu Window ID
 * \param style the Menu style
 * \param hParent the top-level/modal window handle
 * \param x the left position
 * \param y the top position
 * \param w the menu width
 * \param listener the window to handle the WM_COMMAND message
 * \return the global menu handle
 */

#define SMP_Menu_PopupFlat(attr, x, y, w) \
	(HMENU)mrc_extSendAppEventEx(MPS_CODE_SMP_MENU, SMP_MENU_POPUPFLAT, (int32)attr, (int32)x, (int32)y, (int32)w, (int32)0)

	/** @} */

	/**
	 * \name Window Procedure
	 * @{
	 */

/**
 * \brief The simple menu window procedure.
 *
 * \param hMenu the window handle
 * \param Msg the window message
 * \param wParam the first parameter
 * \param lParam the second parameter
 * \return the result of message process 
 */
#define SMP_Menu_WndProc(hMenu, Msg, wParam, lParam) \
	(LRESULT)mrc_extSendAppEventEx(MPS_CODE_SMP_MENU_PROC, (int32)hWnd, (int32)Msg, (int32)wParam, (int32)lParam, (int32)0, (int32)0)
#endif

	/** @} */

/** @} end of smp_menu */

/** @} end of controls */

#endif /* _SMP_MENU_H */

